package frame

import (
	"fmt"
	"regexp"

	"gitee.com/go-mao/mao/libs/binding"
	"gitee.com/go-mao/mao/libs/try"
	"github.com/gin-gonic/gin"
)

type Webline struct {
	*Taskline
	*gin.Context        //上下文
	routerName   string //路由名称
}

func newWebline(c *gin.Context, server *Server) *Webline {
	const key = "webline_object"
	webline := new(Webline)
	webline.Context = c
	taskLine, exists := c.Get(key)
	if !exists {
		taskLine = server.TaskLine()
		c.Set(key, taskLine)
	}
	webline.Taskline = taskLine.(*Taskline)
	return webline
}

// 获取路由名称
func (this *Webline) GetRouterName() string {
	if this.routerName != "" {
		return this.routerName
	}
	return this.Context.GetString("ROUTER_NAME")
}

// 绑定query
func (this *Webline) BindQuery(objectPtr interface{}) {
	err := binding.HttpBindQuery(this.Request, objectPtr)
	this.ifBindError(err)
}

// 绑定json
func (this *Webline) BindJSON(objectPtr interface{}) {
	err := binding.HttpBindJSON(this.Request, objectPtr)
	this.ifBindError(err)
}

// 绑定form
func (this *Webline) BindForm(objectPtr interface{}) {
	err := binding.HttpBindForm(this.Request, objectPtr)
	this.ifBindError(err)
}

// 绑定cookie
func (this *Webline) BindCookie(objectPtr interface{}) {
	err := binding.HttpBindForm(this.Request, objectPtr)
	this.ifBindError(err)
}

// JSON数据输出
func (this *Webline) JSON(code int32, result any, msg ...any) {
	if result == nil {
		result = make(gin.H)
	}
	this.Context.JSON(200, gin.H{
		"code":   code,
		"msg":    fmt.Sprint(msg...),
		"result": result,
	})
}

// 如果数据绑定出错
func (this *Webline) ifBindError(err error) {
	if err == nil {
		return
	}
	switch e := err.(type) {
	case *binding.BindError:
		this.JSON(CODE_WARN, gin.H{"field": e.Field()}, e.Msg())
	case error:
		this.JSON(CODE_WARN, nil, "请求参数错误", err.Error())
	}
	try.Throw(code_nil, "")
}

// 获取所有权限列表
func (this *Webline) GetPermissionList() []*Permission {
	return this.server.permission.getPermissions()
}

// 是否为移动端
func (this *Webline) IsMobile() bool {
	agent := this.GetHeader("User-Agent")
	rxp, _ := regexp.Compile("(?i:mobile|nokia|iphone|ipad|android|samsung|htc|blackberry)")
	return rxp.MatchString(agent)
}
